package com.css.fghs.filter;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.css.constant.Result;
import com.css.session.SessionManager;
import com.css.util.GyUtils;
import com.css.util.RedisUtils;
import com.css.util.SecurityUtils;
import com.css.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;

import static com.css.constant.SsoConstants.COOKIE_TOKEN_KEY;


public class SecurityFilter extends OncePerRequestFilter {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {

        String path = request.getRequestURI();
        return StringUtils.isMatch("/**/swagger-ui/**",path)||StringUtils.isMatch("/**/swagger-resources/**",path)||StringUtils.isMatch("/**/v2/api-docs/",path);
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {

        String servletPath = request.getRequestURI();
        logger.info("请求路径：{}",servletPath);
//        filterChain.doFilter(request, response);
        if (StringUtils.matches(servletPath, SecurityUtils.WHITELIST)){
            filterChain.doFilter(request, response);
        }else {
            String  token= request.getHeader(COOKIE_TOKEN_KEY);

            if (null != token){
                Map yhxx = JSONUtil.toBean(RedisUtils.getHash(token,"yhxx"), Map.class);
                logger.info("通过token查询数据："+ JSONUtil.toJsonStr(yhxx)+"  ;token:"+token);
                if (GyUtils.isNull(yhxx)){
                    try {
                        Map<String, String> headers = new LinkedHashMap<>();
                        Enumeration<String> headerNames = request.getHeaderNames();
                        while (headerNames.hasMoreElements()) {
                            String headerName = headerNames.nextElement();
                            headers.put(headerName, request.getHeader(headerName));
                        }
                        logger.info("请求headers:{}",headers);
                        getOutException(response,Result.err(-1,"用户信息已失效，请重新登录"));
                        return;
                    }catch (Exception e){
                        logger.info("yhxxException:"+e);
                        throw new ServletException("401");
                    }
                }
                SessionManager.get().setYhuuid(GyUtils.object2Str(yhxx.get("yhuuid")));
                SessionManager.get().setYhlx(GyUtils.object2Str(yhxx.get("yhlx")));
                SessionManager.get().setUsername(GyUtils.object2Str(yhxx.get("username")));
                SessionManager.get().setPhone(GyUtils.object2Str(yhxx.get("phone")));
                SessionManager.get().setMap(yhxx);
                logger.info("session：yhuuid"+GyUtils.cast2Str(SessionManager.get().getYhuuid()));
                filterChain.doFilter(request, response);
            }else{
                try {
                    getOutException(response,Result.err(-1,"未获取到用户token"));
                }catch (Exception e){
                    logger.info("yhxxException："+e);
                    throw new ServletException("402");
                }
            }
        }
    }

    @Override
    public void destroy() {
//        SessionManager.get().clear();
        SessionManager.remove();
    }

    public void getOutException(HttpServletResponse response, Result r) throws Exception {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String jsonObject = JSON.toJSONString(r);
        out.println(jsonObject);
        out.flush();
        out.close();
    }
}
